﻿ #region Disclaimer/Info
 
 /////////////////////////////////////////////////////////////////////////////////////////////////
 //
 //   File:		ThemeManager.cs
 //   Website:		http://dexterblogengine.com/
 //   Authors:		http://dexterblogengine.com/About.ashx
 //   Rev:		1
 //   Created:		19/01/2011
 //   Last edit:		19/01/2011
 //   License:		GNU Library General Public License (LGPL)
 // 
 //   For updated news and information please visit http://dexterblogengine.com/
 //   Dexter is hosted to Codeplex at http://dexterblogengine.codeplex.com
 //   For any question contact info@dexterblogengine.com
 //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 #endregion

using System;
using System.Collections.Generic;
using System.Threading;
using Dexter.CallContext;

namespace Dexter.Services.Implementation {
	/// <summary>
	/// 	The Theme Manager Class
	/// </summary>
	public class ThemeManager : IThemeManager {
		/// <summary>
		/// 	Gets or sets the cached configuration
		/// </summary>
		/// <value>The cached.</value>
		protected static readonly IDictionary <string , BlogTheme> Cache;

		/// <summary>
		/// 	The lock object use to manage multi access to the configuration.
		/// </summary>
		protected static readonly ReaderWriterLockSlim @Lock = new ReaderWriterLockSlim ( );

		readonly IUrlBuilderBase urlBuilderRoot;
		readonly IDexterContext dexterContext;

		static ThemeManager ( ) {
			Cache = new Dictionary <string , BlogTheme> ( );
		}

		/// <summary>
		/// 	Initializes a new instance of the <see cref = "ThemeManager" /> class.
		/// </summary>
		/// <param name = "urlBuilderRoot">The URL builder root.</param>
		/// <param name = "context">The context.</param>
		public ThemeManager ( IUrlBuilderBase urlBuilderRoot, IDexterContext context ) {
			this.urlBuilderRoot = urlBuilderRoot;
			this.dexterContext = context;
		}

		/// <summary>
		/// 	Gets the name of the theme by.
		/// </summary>
		/// <param name = "name">The name.</param>
		/// <returns></returns>
		public virtual IBlogTheme GetThemeByName ( string name ) {
			if ( name.IsNullOrEmpty ( ) ) {
				throw new ArgumentException ( "Invalid blog name." , "name" );
			}

			string key = name.ToLowerInvariant ( );

			try {
				Lock.EnterReadLock ( );
				if ( Cache.ContainsKey ( key ) ) {
					return Cache[ key ];
				}
			}
			finally {
				Lock.ExitReadLock ( );
			}

			try {
				Lock.EnterWriteLock ( );

				if ( Cache.ContainsKey ( key ) ) {
					return Cache[ key ];
				}

				var obj = new BlogTheme ( name, urlBuilderRoot, dexterContext );

				var objectToCache = new KeyValuePair <string , BlogTheme> ( key , obj );
				Cache.Add ( objectToCache );

				return obj;
			}
			finally {
				Lock.ExitWriteLock ( );
			}
		}
	}
}
